﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TasksModel;
using System.Net;

namespace TasksUI.Helpers
{
    public class WsHelper : ISynchronizer
    {
        public WsHelper()
        {
        }

        public bool UseSSL { get; set; }

        public string Url { get; set; }

        private ITasksService GetService()
        {
            TasksSoapClient tc = new TasksSoapClient("TasksSoap");
            if (UseSSL)
                tc.Endpoint.Address = new System.ServiceModel.EndpointAddress(Url.Replace("http:", "https:"));
            else
                tc.Endpoint.Address = new System.ServiceModel.EndpointAddress(Url);

            WebRequest.DefaultWebProxy.Credentials = CredentialCache.DefaultNetworkCredentials;

            tc.Open();
            return tc;
        }

        public bool Connect(string login, string password)
        {
            ITasksService ws = GetService();
            return string.Compare(ws.Ping(), TaskLibrary.ApiVersion) >= 0;
        }

        public List<string> GetList()
        {
            ITasksService ws = GetService();
            return ws.GetLibraries();
        }

        public TasksModel.TaskLibrary Get(Guid id)
        {
            ITasksService ws = GetService();
            TaskSerializer<TaskLibrary> ts = new TaskSerializer<TaskLibrary>();
            string xml = ws.GetLibrary(id.ToString("D"));
            return ts.Deserialize(xml);
        }

        public void Synchronize(TasksModel.TaskLibrary tl, bool testOnly, EventHandler<SynchProgress> progress)
        {
            System.Diagnostics.Debug.Assert(tl.SynchSettings is TasksModel.WebServiceSynchSettings);
            TaskLibrary remote;
            string xml;
            TaskSerializer<TaskLibrary> ts = new TaskSerializer<TaskLibrary>();
            ITasksService ws = GetService();

            SynchProgress sp = new SynchProgress();
            sp.TotalItems = 1;
            progress(this, sp);

            TasksModel.SynchSettings.SynchDirection mode = tl.SynchSettings.Mode;
            switch (mode)
            {
                case TasksModel.SynchSettings.SynchDirection.FromExternalOnly:
                    // match local with external
                    xml = ws.GetLibrary(tl.ID.ToString("D"));
                    if (xml != null)
                    {
                        remote = ts.Deserialize(xml);
                        tl.MergeWith(remote);// merge on client
                    }
                    break;
                case TasksModel.SynchSettings.SynchDirection.ToExternalOnly:
                    xml = ts.Serialize(tl);
                    ws.SaveLibrary(xml);// merge on server
                    break;
                case TasksModel.SynchSettings.SynchDirection.TwoWay:
                    xml = ts.Serialize(tl);
                    xml = ws.SaveLibrary(xml);// merge on server
                    remote = ts.Deserialize(xml);
                    tl.MergeWith(remote);// merge on client
                    break;
            }
            if (progress != null)
            {
                sp.CompletedItems = sp.TotalItems;
                progress(this, sp);
            }
        }
    }
}